package com.mt.sdk.ble;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import com.mt.sdk.tools.MTTools;
import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.os.Parcelable;

public class MTBLEDevice implements Parcelable {

	// 设备类型
	private MTBLEDEVICETYPE devicetype = MTBLEDEVICETYPE.BLE; // 设备类型

	// BLE标准参数
	private BluetoothDevice device; // 设备信息
	private byte[] scanRecord; // 广播数据信息
	private int currentRssi = 0; // 当前rssi值

	private Map<Byte, byte[]> recordMap; // 广播数据分解后的数据
	private int avgRssi = 0; // 平均rssi

	// IBeacon参数
	private int major;
	private int minor;
	private int measuedPower;
	private String beaconUUID;

	// 附加参数
	private int beaconid = 0;
	private int battery; // 电量
	private byte setlev = 0; // 部署等级

	public MTBLEDevice(BluetoothDevice device, byte[] scanRecord, int current_rssi) {
		reflashInf(device, scanRecord, current_rssi);
	}

	public void reflashInf(BluetoothDevice device, byte[] scanRecord, int current_rssi) {
		this.device = device;
		this.scanRecord = scanRecord;

		reflashRssi(current_rssi);

		if (scanRecord == null) {
			return;
		}

		this.recordMap = analysisRecord(scanRecord);

		this.devicetype = analysisType(recordMap);

		if (this.devicetype == MTBLEDEVICETYPE.MTBeacon1) {
			analysisBeacon();
			analysisMTBeacon1();
			return;
		}

		if (this.devicetype == MTBLEDEVICETYPE.MTBeacon2) {
			analysisBeacon();
			analysisMTBeacon2();
			return;
		}

		if (this.devicetype == MTBLEDEVICETYPE.MTBeacon3) {
			analysisBeacon();
			analysisMTBeacon3();
			return;
		}

		if (this.devicetype == MTBLEDEVICETYPE.MTBeacon4) {
			analysisBeacon();
			analysisMTBeacon4();
			return;
		}

		if (this.devicetype == MTBLEDEVICETYPE.IBeacon) {
			analysisBeacon();
			return;
		}

		if (this.devicetype == MTBLEDEVICETYPE.MTBLE) {
			analysisMTBLE();
			return;
		}
	}

	public void reflashInf(MTBLEDevice device) {
		reflashInf(device.getDevice(), device.getScanRecord(), device.getCurrentRssi());
	}

	// 分离广播数据
	private static Map<Byte, byte[]> analysisRecord(byte[] scanRecord) {
		Map<Byte, byte[]> recordMap = new HashMap<Byte, byte[]>();
		if (scanRecord == null) {
			return recordMap;
		}

		byte[] values;
		for (int i = 0; i < scanRecord.length;) {
			int lenght = MTTools.convertUint8(scanRecord[i]);
			if ((lenght + i) >= scanRecord.length) {
				return recordMap;
			}

			if ((lenght - 1) < 0) {
				return recordMap;
			}
			values = new byte[lenght - 1];
			MTTools.arraycopy(scanRecord, i + 2, values, 0, lenght - 1);
			if (i + 1 >= scanRecord.length) {
				return null;
			}
			recordMap.put(Byte.valueOf(scanRecord[i + 1]), values);

			i += (lenght + 1);

			if ((i >= (scanRecord.length)) || (0x00 == lenght)) {
				break;
			}
		}

		return recordMap;
	}

	// 判断设备类型
	private final byte[] KRJDSINGLE = { 0x4B, 0x52, 0x4A, 0x44 };

	private MTBLEDEVICETYPE analysisType(Map<Byte, byte[]> recordMap) {

		byte[] value = recordMap.get(Byte.valueOf((byte) (0x06 & 0xFF)));
		if (value != null) {
			byte lrc = 0;
			for (int i = 0; i < value.length; i++) {
				lrc += value[i];
			}
			if (lrc != 0) {
				return MTBLEDEVICETYPE.BLE;
			}

			if (value[0] == 0x10) {
				switch (value[1]) {
				case 0x01:
					return MTBLEDEVICETYPE.MTBLE;
				case 0x02:
					return MTBLEDEVICETYPE.MTBeacon3;
				case 0x03:
					return MTBLEDEVICETYPE.MTBeacon3;
				case 0x04:
					return MTBLEDEVICETYPE.MTBeacon4;
				case 0x05:
					return MTBLEDEVICETYPE.MTBeacon4;
				default:
					break;
				}
				return MTBLEDEVICETYPE.MTBLE;
			}

			return MTBLEDEVICETYPE.MTBLE;
		}

		value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0xFF)));
		if (value != null) {
			if ((value.length == 25) && (value[0] == (byte) (0x4C & 0xFF)) // ibeacon
					&& (value[1] == (byte) (0x00 & 0xFF)) && (value[2] == (byte) (0x02 & 0xFF))) {
				value = recordMap.get(Byte.valueOf((byte) (0xAA & 0xFF)));
				if (value != null) {
					if ((value.length == 2) && (value[0] == 'M')) { // MTBeacon
						return MTBLEDEVICETYPE.MTBeacon1;
					}
					if ((value.length == 3) && (value[0] == 'M')) { // MTBeacon
						return MTBLEDEVICETYPE.MTBeacon2;
					}
				}
				return MTBLEDEVICETYPE.IBeacon;
			}
		}

		value = recordMap.get(Byte.valueOf((byte) (0xFF & 0xFF)));
		if ((value != null) && (value.length == 29)) {
			byte lrc = 0;
			for (int i = 0; i < 20; i++) {
				lrc += value[i];
			}
			if (lrc != 0) {
				return MTBLEDEVICETYPE.BLE;
			}
			if (value[0] == 0x10) {
				switch (value[1]) {
				case 0x10:
					return MTBLEDEVICETYPE.MTWX;
				default:
					break;
				}
				return MTBLEDEVICETYPE.BLE;
			}
			return MTBLEDEVICETYPE.BLE;
		}

		return MTBLEDEVICETYPE.BLE;
	}

	private void reflashRssi(int rssi) {
		this.currentRssi = rssi;
		if (this.avgRssi == 0) {
			this.avgRssi = rssi;
		} else {
			this.avgRssi = (this.avgRssi + this.currentRssi) / 2;
		}
	}

	// MTBLE
	private static Map<Byte, String> setLvName = new HashMap<Byte, String>();

	static {
		setLvName.put(Byte.valueOf((byte) 0), "可连接");
		setLvName.put(Byte.valueOf((byte) 1), "密码连接");
		setLvName.put(Byte.valueOf((byte) 2), "临时部署");
		setLvName.put(Byte.valueOf((byte) 3), "永久部署");
	}

	// 获取部署名称
	public static String getSetLvName(byte index) {
		String result = setLvName.get(Byte.valueOf(index));

		if (result == null) {
			result = "unknow name";
		}
		return result;
	}

	public MTBLEDEVICETYPE getDevicetype() {
		return devicetype;
	}

	public byte[] getScanRecord() {
		return scanRecord;
	}

	public Map<Byte, byte[]> getrecordMap() {
		return recordMap;
	}

	public BluetoothDevice getDevice() {
		return device;
	}

	public int getCurrentRssi() {
		return currentRssi;
	}

	public int getAvgRssi() {
		return avgRssi;
	}

	public double getCurrentDistance() {
		return CalculateDistance(getCurrentRssi(), measuedPower);
	}

	public double getAverageDistance() {
		return CalculateDistance(getAvgRssi(), measuedPower);
	}

	public int getMajor() {
		return major;
	}

	public int getMinor() {
		return minor;
	}

	public int getMeasuedPower() {
		return measuedPower;
	}

	public String getBeaconUUID() {
		return beaconUUID;
	}

	public int getBattery() {
		return battery;
	}

	public byte getSetlev() {
		return setlev;
	}

	public int getBeaconid() {
		return beaconid;
	}

	public Map<Byte, byte[]> getRecordMap() {
		return recordMap;
	}

	// 分析beacon参数
	private void analysisBeacon() {
		byte[] value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0xff)));
		if (value.length != 25) {
			return;
		}
		major = MTTools.convertUint16(value[20], value[21]);
		minor = MTTools.convertUint16(value[22], value[23]);
		measuedPower = value[24];

		beaconUUID = "";
		for (int j = 4; j < 20; j++) { // uuid
			if ((j == 8) || (j == 10) || (j == 12) || (j == 14))
				beaconUUID += '-';
			beaconUUID += MTTools.convertByteToString(value[j]);
		}
		beaconUUID = beaconUUID.toUpperCase(Locale.getDefault());
	}

	// 分析MTBeacon1参数
	private boolean analysisMTBeacon1() {
		byte[] value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0xAA)));

		if (value == null) {
			return false;
		}
		if (value.length != 2) {
			return false;
		}
		this.battery = MTTools.convertUint8(value[1]);

		return true;
	}

	// 分析MTBeacon2参数
	private boolean analysisMTBeacon2() {
		byte[] value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0xAA)));

		if (value == null) {
			return false;
		}
		if (value.length != 3) {
			return false;
		}
		this.battery = MTTools.convertUint8(value[1]);
		this.setlev = (byte) (value[2] - 'A');
		return true;
	}

	// 分析MTBeacon3参数
	private boolean analysisMTBeacon3() {

		byte[] value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0x06)));
		if ((value == null) || (value.length != 16)) {
			return false;
		}

		this.battery = MTTools.convertUint8(value[2]);
		this.setlev = (byte) (value[8] - 'A');

		return true;
	}

	// 分析MTBeacon4参数
	private boolean analysisMTBeacon4() {
		byte[] value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0x06)));
		if ((value == null) || (value.length != 16)) {
			return false;
		}

		this.battery = (int) (MTTools.convertUint8(value[2]));
		this.beaconid = value[3] & 0x0F;
		this.setlev = (byte) (value[8] - 'A');

		if (this.battery > 100) {
			this.battery = 100;
		}

		return true;
	}

	// 分析MTBLE参数
	private boolean analysisMTBLE() {
		byte[] value = recordMap.get(Byte.valueOf(MTTools.convertIntToByte(0x06)));
		if (value != null) {
			battery = MTTools.convertUint8(value[2]);
		}
		return true;
	}

	// 换算距离
	private static double CalculateDistance(int rssi, int measuedPower) {
		double distance = 0;
		double ratio = rssi * 1.0 / measuedPower;
		if (ratio < 1.0) {
			distance = Math.pow(ratio, 10);
		} else {
			distance = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
		}

		return distance;
	}

	// 设备类型
	public enum MTBLEDEVICETYPE {
		BLE, MTBLE, IBeacon, MTBeacon1, MTBeacon2, MTBeacon3, MTBeacon4, MTWX
	}

	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub

	}

}
